#include "serialportthread.h"
#include "serialport.h"

#include <QDateTime>
#include <QMutexLocker>
#include <QDebug>

SerialPortThread::SerialPortThread(CMDLib _cmds,SerialPort *_SerialPort,QObject *parent)
    : QThread(parent)
//    , cacheForRead(false)
    , ptr_SerialPort(_SerialPort)
    , cmds(_cmds)
    , running(true)
    , allCallFlag(true)
{
    limitSize = 2*cmds.cmd_totalcall.size()+2;
};

SerialPortThread::~SerialPortThread()
{
    running=false;
	try{
        this->terminate();
        this->wait();
        qInfo() << "SerialPortThread::destroy\n";
    }catch(...){
        qDebug() << "SerialPortThread::destroy fail\n";
    }
};

void SerialPortThread::run()
{
    this->msleep(30000);
    allCallTime = getMsec();
    qint64 curTime = getMsec();
    while (running) {
        curTime = getMsec();
        if(allCallFlag&&(allCallTime+cmds.time_interval)<curTime){
            allCallTime = curTime;
            allCall();
//            qInfo()<<QString("curTime=%1,time_interval=%2").arg(curTime).arg(cmds.time_interval);
        }
//        if(cacheForRead){
//            emit readData();
//            qInfo()<<QString("cacheForRead(%1),readData").arg(cacheForRead);
//            cacheForRead = false;
//        }
        doCmd();
        this->msleep(100);
    }
    exec();
};

//void SerialPortThread::cacheForReady()
//{
//    cacheForRead = true;
//};

void SerialPortThread::AddMsg(QString cmd, bool u16f,bool allCallf)
{
    QMutexLocker locker(&dcmds_mutex);
    if(dcms.size()>limitSize&&allCallf)
        return;
    DownCmd dcmd(cmd,u16f);
    allCallf?dcms.enqueue(dcmd):dcms.prepend(dcmd);
//    qInfo()<<QString("AddMsg:%1").arg(cmd);
}

void SerialPortThread::setAllCall(bool openflag)
{
    allCallFlag = openflag;
}

bool SerialPortThread::getAllCall()
{
    return allCallFlag;
}

qint64 SerialPortThread::getMsec()
{
    return QDateTime::currentMSecsSinceEpoch();
}

void SerialPortThread::allCall()
{
    for(int i=0; i<cmds.cmd_totalcall.size(); i++){
        AddMsg(cmds.cmd_totalcall[i],true);
    }
};

void SerialPortThread::doCmd()
{
    emit TimeUp();
    QMutexLocker locker(&dcmds_mutex);
    if(dcms.empty())
        return;
    DownCmd dcmd = dcms.dequeue();
    emit sendMsg(dcmd.cmd,dcmd.u16f);
};

//////////////////////////////////////////////////////////////////

MsgAnalysisThread::MsgAnalysisThread(SerialPort *_SerialPort,QObject *parent)
    : QThread(parent)
    , ptr_SerialPort(_SerialPort)
    , running(true)
    , limitSize(100)
{

}

MsgAnalysisThread::~MsgAnalysisThread()
{
    running=false;
    try{
        this->terminate();
        this->wait();
        qInfo() << "MsgAnalysisThread::destroy\n";
    }catch(...){
        qDebug() << "MsgAnalysisThread::destroy fail\n";
    }
}

void MsgAnalysisThread::run()
{
    while (running) {
        doCmd();
        this->msleep(100);
    }
    exec();
};

void MsgAnalysisThread::AddMsg(QString _ret, QString _send)
{
    upcms_mutex.lock();
    if(upcms.size()>limitSize){      
        upcms.dequeue();
//        qInfo()<<QString("AddMsg move UpCmd");
    }
    UpCmd ucmd(_ret,_send);
    upcms.append(ucmd);
    upcms_mutex.unlock();
//    qInfo()<<QString("AddMsg:%1,%2").arg(_ret).arg(_send);
}

void MsgAnalysisThread::doCmd()
{
    UpCmd ucmd;
    upcms_mutex.lock();
    if(!upcms.empty()){
        ucmd = upcms.dequeue();
    }
    upcms_mutex.unlock();
    if(!ucmd.retCmd.isEmpty()){
        ptr_SerialPort->uncodeMsg(ucmd.retCmd.toUpper(),ucmd.downCmd.toUpper());
//        qInfo()<<QString("doCmd:%1,%2").arg(ucmd.retCmd.toUpper()).arg(ucmd.downCmd.toUpper());
    }
}
